'''
https://leetcode.cn/problems/bu-ke-pai-zhong-de-shun-zi-lcof/
'''

from typing import List
from collections import Counter

'''判断顺子'''
class Solution01:
    def isStraight(self, nums: List[int]) -> bool:
        zero_nums = nums.count(0)
        temp_set = list(set(nums)) # set()会打乱内部数据的排序，转换后需要再进行一次排序
        temp_set.sort()
        # print('temp_set:', temp_set)
        # 判断是否存在重复数字，分存不存在0两种情况
        if zero_nums != 0: # 存在0
            if len(temp_set) + zero_nums - 1 != len(nums) : # 存在非0重复数字
                return False
            # 只有一个数字其余全是0，或者只有0没有其他数字
            if len(temp_set) < 3:  # 只有两种数字
                return True
        else:  # 不存在0
            if len(temp_set) != len(nums): # 但有重复数字
                return False

        # 非特殊情况，无论0在不在，判断两非0数字的间距，只要比数组长度小就是顺子
        max_num = temp_set[-1]
        min_num = temp_set[0] if temp_set[0] != 0 else temp_set[1] # 注意0存在与否的情况
        # print('min_num:', min_num)
        if max_num - min_num < len(nums):
            return True
        else:
            return False
# 精简版
class Solution01_2:
    def isStraight(self, nums: List[int]) -> bool:
        joker = 0
        nums.sort() # 数组排序
        for i in range(4): # 多张牌可以改成len(nums)-1
            if nums[i] == 0: joker += 1 # 统计大小王数量
            elif nums[i] == nums[i + 1]: return False # 若有重复，提前返回 false
        return nums[4] - nums[joker] < 5 # 最大牌 - 最小牌 < 5 则可构成顺子


'''     顺子分组    '''
'''
https://leetcode.cn/problems/hand-of-straights/
要分组的数据：hand
每一组的数据数量：groupSize
'''
class Solution02:
    def isNStraightHand(self, hand: List[int], groupSize: int) -> bool:
        if len(hand) % groupSize > 0: # 不能整除的不要
            return False
        hand.sort()
        '''
        Counter(hand) 把列表hand变成类似字典的类，key = hand[i], value = hand.count(hand[i])
        即把列表中每个数出现的次数统计下来
        '''
        cnt = Counter(hand)
        res = []
        for x in hand:
            temp_list = []
            if cnt[x] == 0: # 如果牌没了就算了，但如果牌还在，那就进行下面的for循环来分组
                # 这个数字已经被全部取走了
                # 选择顺子起点数值
                continue
            for num in range(x, x + groupSize):
                # range(x, x + groupSize) 顺子是连续的，所以需要找到x, x + groupSize之间的数
                if cnt[num] == 0:
                    # 当需要的数已经没有了，那么就没法组成顺子
                    return False
                cnt[num] -= 1 # 取走一个数就-1
                temp_list.append(num)
            res.append(temp_list)
        print(res)
        return True


if __name__ == '__main__':
    '''     判断顺子    '''
    s = Solution01()
    input001 = [3, 0, 9, 0, 2]
    print(s.isStraight(input001))

    '''     顺子分组    '''
    hand001 = [1, 2, 3, 6, 2, 3, 4, 7, 8]
    groupSize001 = 3
    hand002 = [1, 2, 3, 4, 5]
    groupSize002 = 4
    hand003 = [1, 2, 3, 4]
    groupSize003 = 1

    s = Solution02()
    print(s.isNStraightHand(hand001, groupSize001))
    print(s.isNStraightHand(hand002, groupSize002))
    print(s.isNStraightHand(hand003, groupSize003))

    '''     测试      '''
    a = [1, 2, 3, 4]
    print(type(Counter(a)))


